#ifndef _LIST_H_
#define _LIST_H_


#define INLINE static inline

struct list_node {
    struct list_node *next;
    struct list_node *prev;
};

typedef struct list_node list_t;


#define container_of(ptr, type, member) \
    ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))

#define list_entry(node, type, member) \
    container_of(node, type, member)

#define list_for_each(pos, head) \
    for (pos = (head)->next; pos != (head); pos = pos->next)


/* init list head
 * */
INLINE void list_init(list_t *l)
{
    l->next = l->prev = l;
}

INLINE void list_insert(list_t *l, list_t *n)
{
    l->next->prev = n;
    n->next = l->next;

    l->next = n;
    n->prev = l;
}

INLINE void list_insert_before(list_t *l, list_t *n)
{
    l->prev->next = n;
    n->prev = l->prev;

    l->prev = n;
    n->next = l;
}

INLINE void list_remove(list_t *n)
{
    n->next->prev = n->prev;
    n->prev->next = n->next;

    n->next = n->prev = n;
}

INLINE int list_is_empty(const list_t *l)
{
    return (l->next == l);
}

INLINE int list_len(const list_t *l)
{
    unsigned int len = 0;
    const list_t *p = l;
    while (p->next != l) {
        p = p->next;
        len++;
    }

    return len;
}

#endif
